﻿using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geoprocessing;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace MapFormsApp.Services
{
    /// <summary>
    /// 地理数据管理核心类（封装Workspace操作）
    /// </summary>
    public class DataManager : IDisposable
    {
        private IWorkspace _workspace;
        private bool _isEditing = false;

        #region 构造函数与初始化
        /// <summary>
        /// 连接文件地理数据库
        /// </summary>
        public DataManager(string gdbPath)
        {
            IWorkspaceFactory workspaceFactory = new FileGDBWorkspaceFactoryClass();
            _workspace = workspaceFactory.OpenFromFile(gdbPath, 0);
        }

        /// <summary>
        /// 获取工作空间引用
        /// </summary>
        public IWorkspace Workspace => _workspace;
        #endregion

        #region 要素类操作
        /// <summary>
        /// 打开要素类（自动转换坐标系）
        /// </summary>
        public IFeatureClass OpenFeatureClass(string name, ISpatialReference targetSpatialRef = null)
        {
            IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)_workspace;
            IFeatureClass featureClass = featureWorkspace.OpenFeatureClass(name);

            if (targetSpatialRef != null)
            {
                IGeoDataset geoDataset = (IGeoDataset)featureClass;
                //if (!geoDataset.SpatialReference.IsSame(targetSpatialRef))
                //{
                //    return ProjectFeatureClass(featureClass, targetSpatialRef);
                //}
            }
            return featureClass;
        }

        /// <summary>
        /// 创建临时要素类（用于存储分析结果）
        /// </summary>
        //public IFeatureClass CreateTempFeatureClass(IGeometryType geometryType, ISpatialReference spatialRef)
        //{
        //    IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)_workspace;

        //    IFields fields = new FieldsClass();
        //    IFieldsEdit fieldsEdit = (IFieldsEdit)fields;

        //    // 添加ObjectID字段
        //    fieldsEdit.AddField(new UIDClass { Value = "esriGeoDatabase.ObjectID" } as IField);

        //    // 添加几何字段
        //    IGeometryDef geometryDef = new GeometryDefClass();
        //    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
        //    geometryDefEdit.GeometryType_2 = geometryType;
        //    geometryDefEdit.SpatialReference_2 = spatialRef;

        //    IField field = new FieldClass();
        //    IFieldEdit fieldEdit = (IFieldEdit)field;
        //    fieldEdit.Name_2 = "Shape";
        //    fieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry;
        //    fieldEdit.GeometryDef_2 = geometryDef;
        //    fieldsEdit.AddField(field);

        //    return featureWorkspace.CreateFeatureClass(
        //        "Temp_" + Guid.NewGuid().ToString("N"),
        //        fields,
        //        null, null, esriFeatureType.esriFTSimple,
        //        "Shape",
        //        ""
        //    );
        //}
        #endregion

        #region 网络数据集操作
        /// <summary>
        /// 获取网络数据集（核心方法）
        /// </summary>
        public INetworkDataset GetNetworkDataset(string name)
        {
            IDatasetContainer3 dsContainer = (IDatasetContainer3)_workspace;
            IDataset dataset = dsContainer.get_DatasetByName(esriDatasetType.esriDTNetworkDataset, name);
            return dataset as INetworkDataset;
        }
        #endregion

        #region 事务管理
        /// <summary>
        /// 启动编辑会话（支持长事务）
        /// </summary>
        public void StartEditing(bool withUndoRedo = false)
        {
            IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)_workspace;
            if (!workspaceEdit.IsBeingEdited())
            {
                workspaceEdit.StartEditing(withUndoRedo);
                workspaceEdit.StartEditOperation();
                _isEditing = true;
            }
        }

        /// <summary>
        /// 提交编辑操作
        /// </summary>
        public void CommitEdits()
        {
            if (!_isEditing) return;

            IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)_workspace;
            try
            {
                workspaceEdit.StopEditOperation();
                workspaceEdit.StopEditing(true);
            }
            finally
            {
                _isEditing = false;
            }
        }

        /// <summary>
        /// 回滚编辑操作
        /// </summary>
        public void RollbackEdits()
        {
            if (!_isEditing) return;

            IWorkspaceEdit workspaceEdit = (IWorkspaceEdit)_workspace;
            try
            {
                workspaceEdit.AbortEditOperation();
                workspaceEdit.StopEditing(false);
            }
            finally
            {
                _isEditing = false;
            }
        }
        #endregion

        #region 实用方法
        /// <summary>
        /// 投影要素类到目标坐标系
        /// </summary>
        private IFeatureClass ProjectFeatureClass(IFeatureClass sourceFeatureClass, ISpatialReference targetSpatialRef)
        {
            IGeoDataset inputGeoDataset = (IGeoDataset)sourceFeatureClass;
            IGeoDataset outputGeoDataset = PerformProjection(inputGeoDataset, targetSpatialRef);
            return (IFeatureClass)outputGeoDataset;
        }

        /// <summary>
        /// 执行坐标系转换（使用IGeoProcessor）
        /// </summary>
        private IGeoDataset PerformProjection(IGeoDataset inputDataset, ISpatialReference targetSpatialRef)
        {
            IGeoProcessor2 gp = new GeoProcessorClass();
            IVariantArray parameters = new VarArrayClass();

            parameters.Add(inputDataset); // 输入数据
            parameters.Add(targetSpatialRef); // 目标坐标系
            parameters.Add("PRESERVE_SHAPE"); // 投影方法

            IGeoDataset result = gp.Execute("Project_management", parameters, null) as IGeoDataset;
            return result;
        }

        /// <summary>
        /// 获取所有要素类列表
        /// </summary>
        public List<string> ListFeatureClasses()
        {
            var names = new List<string>();
            //IDatasetContainer dsContainer = (IDatasetContainer)_workspace;

            //IEnumDataset enumDataset = dsContainer.Datasets[esriDatasetType.esriDTFeatureClass];
            //IDataset dataset;
            //while ((dataset = enumDataset.Next()) != null)
            //{
            //    names.Add(dataset.Name);
            //}
            return names;
        }
        #endregion

        #region 资源清理
        private bool _disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (_disposed) return;

            if (disposing)
            {
                if (_isEditing) RollbackEdits();

                if (_workspace != null)
                {
                    Marshal.ReleaseComObject(_workspace);
                    _workspace = null;
                }
            }
            _disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~DataManager() => Dispose(false);
        #endregion
    }
}